package com.xmy.readwrite;

import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 读写锁
 */
public class ReadWriteLockDemo {
    public static void main(String[] args) throws InterruptedException {
        MyCache myCache = new MyCache();
        CountDownLatch latch = new CountDownLatch(10);
        System.out.println("初始数据为："+myCache.getList());
        // 写入
        for (int i = 1; i <=5 ; i++) {
            int finalI = i;
            new Thread(()->{
                myCache.put(finalI-1,finalI+"");//写入
                latch.countDown();
            },String.valueOf(finalI)).start();

            new Thread(()->{
                myCache.get(finalI-1); // 读取
                latch.countDown();
            },String.valueOf(finalI)).start();
        }
        latch.await();
        System.out.println("当前数据为："+myCache.getList());

    }
}

/**
 * 自定义缓存
 */
class MyCache{
    private volatile List<String> list = Arrays.asList("one","two","three","four","five");

    public List<String> getList() {
        return list;
    }

    //创建读写锁
    final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    //存, 写入的时候，只能有一个线程进行操作
    public void put(Integer index,String value){
        readWriteLock.writeLock().lock();//写锁加锁
        try {
            System.out.println(Thread.currentThread().getName()+"写入索引为"+index+"处");
            list.set(index,value);
            System.out.println(Thread.currentThread().getName()+"写入OK");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.writeLock().unlock();//写锁解锁
        }
    }

    // 取， 读的时候，所有线程都可以读
    public void get(Integer index){
        readWriteLock.readLock().lock();// 读锁加锁
        try {
            System.out.println(Thread.currentThread().getName()+"读取索引为"+index+"的值");
            String value = list.get(index);
            System.out.println(Thread.currentThread().getName()+"读取OK，值为"+value);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readWriteLock.readLock().unlock(); // 读锁解锁
        }
    }
}